#ifndef _TCP_SERVER_H_
#define _TCP_SERVER_H_

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <pthread.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdbool.h>
#include <time.h>

#include "get_weather.h"  // 获取天气信息头文件
#include "../inc/pthread_pool.h" // 线程池头文件

#define MSG_MAX_LEN 256 // 消息最大长度
#define IP_LEN 16       // ip地址最大长度
#define SEND_MODE_BASE 1
#define SEND_MODE_EXIT 2
#define EXIT_MASK "exit"             // 退出
#define PRIVATE_CHAT "P_Chat"        // 私聊
#define WE_CHAT "W_Chat"             // 群聊
#define SHOW_WEATHER "S_Weat"        // 天气
#define SHOW_ONLINE_CLI "ONLINE_Cli" // 在线客户端
#define TIME_MASK "time"             // 时间

// 变量声明
typedef struct server_inf *P_SBI; // 服务器广播信息结构体指针
typedef struct pthread_pool_inf *P_SPI;

// 设计在线的客户端链表结点类型
typedef struct client_node
{
    /**客户端线程id、套接字、ip**/
    pthread_t cli_pid;
    int cli_fd;
    char cli_ip[IP_LEN];

    P_SBI server_inf_struct;

    struct client_node *next, *prev; // 指针域

} CN, *P_CN;

// 设计TCP服务器主结构体
typedef struct server_inf
{
    /**服务器套接字、端口号**/
    int ser_fd;
    int ser_port;

    /**互斥锁**/
    pthread_mutex_t mutex;

    /**线程池**/
    P_SPI pthread_pool;

    /**等待客户端连接的线程的ID**/
    pthread_t wait_id;
    /**在线的客户端链表头结点**/
    P_CN online_client_head;

} SBI, *P_SBI;

/**函数声明**/
P_SBI Tcp_Server_Init(int ser_port);
P_CN Create_Client_Node();
void *Wait_For_Client_Connect(void *arg);
bool Broadcast_Task(P_CN client_node);
bool Add_Client_Node(P_CN client_head, P_CN new_client_node);
bool Del_Client_Node(P_CN client_node);
bool Send_All_Client(P_CN client_node, char *msg, int send_mode);
bool Funtiction_Select(P_SBI server_inf_struct);
bool Show_Online_Client(P_SBI server_inf_struct);
bool TCP_Server_Destroy(P_SBI server_inf_struct);
void *Mode_Select(void *arg);
bool Send_Onlie_Client(P_SBI server_inf_struct, P_CN client_node);
bool HandlePrivateChat(P_SBI server_inf_struct, char *msg, char *sender_ip);
char *Get_Time();
#endif